package org.moonlight.jvm.classfile.attribute.debuginfo;

import lombok.Getter;
import org.moonlight.jvm.classfile.ClassReader;
import org.moonlight.jvm.classfile.attribute.AttributeInfo;

/**
 * LineNumberTable 属性表存放方法的行号信息，LocalVariableTable 属性表中存放方法的局部变量信息。
 * 这两种属性和 SourceFile 属性都属于调试信息，都不是运行时必需的。
 *
 * LineNumberTable和LocalVariableTable属性表在结构上很像。其结构定义如下:
 *   LocalVariableTable_attribute {
 *       u2 attribute_name_index
 *       u4 attribute_length
 *       u2 local_variable_table_length
 *       {
 *         u2 start_pc;
 *         u2 length;
 *         u2 name_index;
 *         u2 descriptor_index;
 *         u2 index;
 *       } local_variable_table[local_variable_table_length]
 *   }
 *
 * @author Moonlight
 * @createTime 2023/8/15 17:15
 **/
@Getter
public class LocalVariableTableAttribute implements AttributeInfo {

    private LocalVariableTableEntry[] localVariableTable;

    @Override
    public void readInfo(ClassReader reader) {
        int localVarTableLength = reader.readUint16();
        LocalVariableTableEntry[] localVariableTable = new LocalVariableTableEntry[localVarTableLength];
        for (int i = 0; i < localVarTableLength; i++) {
            localVariableTable[i] = new LocalVariableTableEntry(
                    reader.readUint16(), reader.readUint16(), reader.readUint16(), reader.readUint16(), reader.readUint16()
            );
        }
        this.localVariableTable = localVariableTable;
    }

    @Getter
    static class LocalVariableTableEntry {
        private final int startPc;
        private final int length;
        private final int nameIdx;
        private final int descriptorIdx;
        private final int idx;

        LocalVariableTableEntry(int startPc, int length, int nameIdx, int descriptorIdx, int idx) {
            this.startPc = startPc;
            this.length = length;
            this.nameIdx = nameIdx;
            this.descriptorIdx = descriptorIdx;
            this.idx = idx;
        }
    }

}
